#ifndef __CORE_COMMON_SINGLETON_H_INCLUDE__
#define __CORE_COMMON_SINGLETON_H_INCLUDE__

#include <assert.h>
#include <stdlib.h>

namespace core{ namespace common
{
	template<class T> class Singleton
	{
	private:
		static T *instance_;

	protected:
		Singleton(){}
		virtual ~Singleton(){}

	public:
		static bool initInstance()
		{
			if( NULL != instance_ ) return false;
	
			instance_ = new T;
			return true;
		}

		template<class CLS_TYPE, class ARG_TYPE> static bool initInstance( ARG_TYPE nArg )
		{
			if( NULL != instance_ ) return false;

			instance_ = new CLS_TYPE(nArg);
			return true;
		}

		static bool exitInstance()
		{
			if( NULL == instance_ ) return false;

			delete instance_;
			instance_ = NULL;
			return true;
		}

		inline static T *getInstance()
		{
			return instance_;
		}

		inline static T &instance()
		{
			assert(NULL != instance_);
			return *instance_;
		}

		template<class CLS_TYPE> inline static CLS_TYPE *getSubInstance()
		{
			if( NULL == instance_ )
			{
				return NULL;
			}

			return dynamic_cast<CLS_TYPE *>(instance_);
		}

		template<class CLS_TYPE> inline static CLS_TYPE &subInstance()
		{
			assert(NULL != instance_);
			return *dynamic_cast<CLS_TYPE *>(instance_);
		}
	};

	template<class T> T *core::common::Singleton<T>::instance_ = NULL;
}}

#endif //__CORE_COMMON_SINGLETON_H_INCLUDE__

